package com.meibao.order.service;

import com.meibao.auth.entity.UserInfo;
import com.meibao.common.dto.CartDto;
import com.meibao.common.enums.ExceptionEnums;
import com.meibao.common.exception.MbException;
import com.meibao.common.utils.IdWorker;
import com.meibao.item.pojo.Sku;
import com.meibao.order.client.AddressClient;
import com.meibao.order.client.GoodsClient;
import com.meibao.order.dto.AddressDTO;
import com.meibao.order.dto.OrderDto;
import com.meibao.order.dto.OrderStatusEnum;
import com.meibao.order.interceptor.UserInterceptor;
import com.meibao.order.mapper.OrderDetailMapper;
import com.meibao.order.mapper.OrderMapper;
import com.meibao.order.mapper.OrderStatusMapper;
import com.meibao.order.pojo.Order;
import com.meibao.order.pojo.OrderDetail;
import com.meibao.order.pojo.OrderStatus;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private OrderStatusMapper orderStatusMapper;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private GoodsClient goodsClient;

    @Transactional
    public Long createOrder(OrderDto orderDto) {

        //1 新增订单

        //1.1 订单编号  基本信息
        //生成订单ID，采用自己的算法生成订单ID
        long orderId = idWorker.nextId();
        //填充order，订单中的用户信息数据从Token中获取，填充到order中
        Order order = new Order();
        order.setCreateTime(new Date());
        order.setOrderId(orderId);
        order.setPaymentType(orderDto.getPaymentType());
        order.setPostFee(0L);  //// TODO 调用物流信息，根据地址计算邮费
        //1.2 用户信息
        //获取用户信息
        UserInfo user = UserInterceptor.getUser();
        order.setUserId(user.getId());
        order.setBuyerNick(user.getUsername());
        order.setBuyerRate(false);
        //1.3 收货人信息
        //收货人地址信息，应该从数据库中物流信息中获取，这里使用的是假的数据
        AddressDTO addressDTO = AddressClient.findById(orderDto.getAddressId());
        if (addressDTO == null) {
            // 商品不存在，抛出异常
            throw new MbException(ExceptionEnums.RECEIVER_ADDRESS_NOT_FOUND);
        }
        order.setReceiver(addressDTO.getName());
        order.setReceiverAddress(addressDTO.getAddress());
        order.setReceiverCity(addressDTO.getCity());
        order.setReceiverDistrict(addressDTO.getDistrict());
        order.setReceiverMobile(addressDTO.getPhone());
        order.setReceiverZip(addressDTO.getZipCode());
        order.setReceiverState(addressDTO.getState());
        //1.4 金额 把orderDto转化成map，其中key为skuId,值为购物车中该sku的购买数量
        Map<Long, Integer> skuNumMap = orderDto.getCarts().stream().collect(Collectors.toMap(CartDto::getSkuId, CartDto::getNum));

        //查询商品信息，根据skuIds批量查询sku详情
        List<Sku> skus = goodsClient.querySkuByIds(new ArrayList<>(skuNumMap.keySet()));

        //准备orderDetail
        ArrayList<OrderDetail> details = new ArrayList<>();

        long totalPay = 0L;
        for (Sku sku : skus) {
            Integer num = skuNumMap.get(sku.getId());
            totalPay += num * sku.getPrice();

            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orderId);
            orderDetail.setOwnSpec(sku.getOwnSpec());
            orderDetail.setSkuId(sku.getId());
            orderDetail.setTitle(sku.getTitle());
            orderDetail.setNum(num);
            orderDetail.setPrice(sku.getPrice().longValue());
            orderDetail.setImage(StringUtils.substringBefore(sku.getImages(), ","));

            details.add(orderDetail);
        }
        order.setTotalPay(totalPay);
        //总金额 + 邮费 - 优惠金额
        order.setActualPay(totalPay + order.getPostFee() - 0);
        //1.5写入redis
        int count = orderMapper.insertSelective(order);
        if (count != 1) {
            log.error("[创建订单] 创建订单失败  orderId:{}",orderId);
            throw new MbException(ExceptionEnums.CREATE_ORDER_ERROR);
        }
        //2 新增订单详情
        count = orderDetailMapper.insertList(details);
        if (count != 1) {
            log.error("[创建订单] 创建订单失败  orderId:{}",orderId);
            throw new MbException(ExceptionEnums.CREATE_ORDER_ERROR);
        }
        //3 新增订单状态
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(orderId);
        orderStatus.setStatus(OrderStatusEnum.INIT.value());
        orderStatus.setCreateTime(new Date());
        count = orderStatusMapper.insertSelective(orderStatus);
        if (count != 1) {
            log.error("[创建订单] 创建订单失败  orderId:{}",orderId);
            throw new MbException(ExceptionEnums.CREATE_ORDER_ERROR);
        }
        //4 减库存
        List<CartDto> cartDtos = orderDto.getCarts();
        goodsClient.decreaseStock(cartDtos);
        return orderId;
    }

    public Order queryOrderById(Long orderId) {
        //查询订单
        Order order = orderMapper.selectByPrimaryKey(orderId);
        if (order == null) {
            //不存在
            throw new MbException(ExceptionEnums.ORDER_NOT_FOUND);
        }
        //查询订单详情
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orderId);
        List<OrderDetail> orderDetails = orderDetailMapper.select(orderDetail);
        if(CollectionUtils.isEmpty(orderDetails)){
            //不存在
            throw new MbException(ExceptionEnums.ORDER_DETAIL_NOT_FOUND);
        }
        order.setOrderDetails(orderDetails);

        //查询订单状态
        OrderStatus orderStatus = orderStatusMapper.selectByPrimaryKey(orderId);
        if (orderStatus == null) {
            //不存在
            throw new MbException(ExceptionEnums.ORDER_STATUS_NOT_FOUND);
        }
        order.setOrderStatus(orderStatus);
        return order;

    }
}
